from redis_adapter import RedisCache
from query import *

# flight_cache = {'flight_id': [reserve, volume]}
# bus_cache = {'bus_id': [reserve, volume]}
# hotel_cache = {'hotel_id': [reserve, volume]}


class ReserveService:
    def __init__(self):
        self._flight_cache = RedisCache('flight')
        self._bus_cache = RedisCache('bus')
        self._hotel_cache = RedisCache('hotel')
        self.caches = {
            'flight': self._flight_cache,
            'bus': self._bus_cache,
            'hotel': self._hotel_cache
        }

    def update_cache(self, service_type, service_id):
        ''' update cache by data from SQL database '''
        if service_type == 'flight':
            reserve = get_flight_reserve(service_id)
            if reserve == '_no_this_service':
                return reserve
            volume = get_flight_info(service_id).volume
            self._flight_cache[service_id] = [reserve, volume]
        elif service_type == 'bus':
            reserve = get_bus_reserve(service_id)
            if reserve == '_no_this_service':
                return reserve
            volume = get_bus_info(service_id).volume
            self._bus_cache[service_id] = [reserve, volume]
        elif service_type == 'hotel':
            reserve = get_hotel_reserve(service_id)
            if reserve == '_no_this_service':
                return reserve
            volume = get_hotel_info(service_id).volume
            self._hotel_cache[service_id] = [reserve, volume]
        return [reserve, volume]

    def get_cache(self, service_type, service_id):
        ''' get reserved count and total volume from cache '''
        if not self.caches.get(service_type):
            return '_no_this_service_type'
        res_cache = self.caches[service_type]
        if res_cache.get(service_id):
            return res_cache[service_id]  # [reserve, volume]
        return self.update_cache(service_type, service_id)

    def make_reserve(self, service_type, service_id, user_id):
        result = self.get_cache(service_type, service_id)
        if isinstance(result, str) and result != 'ok':
            return result
        [reserve, volume] = result
        if reserve >= volume:
            return '_has_no_vacant'
        if service_type == 'flight':
            result = make_flight_reserve(user_id, service_id)
            if result == 'ok':
                self._flight_cache[service_id] = [reserve + 1, volume]
        elif service_type == 'bus':
            result = make_bus_reserve(user_id, service_id)
            if result == 'ok':
                self._bus_cache[service_id] = [reserve + 1, volume]  # update cache
        elif service_type == 'hotel':
            result = make_hotel_reserve(user_id, service_id)
            if result == 'ok':
                self._hotel_cache[service_id] = [reserve + 1, volume]  # update cache
        else:
            return '_no_this_service'
        return result

    def cancel_reserve(self, service_type, service_id, user_id):
        result = self.get_cache(service_type, service_id)
        if isinstance(result, str) and result != 'ok':
            return result
        [reserve, volume] = result
        if reserve == 0:
            return '_no_this_reserve'
        if service_type == 'flight':
            result = cancel_flight_reserve(user_id, service_id)
            if result == 'ok':
                self._flight_cache[service_id] = [reserve - 1, volume]
        elif service_type == 'bus':
            result = cancel_bus_reserve(user_id, service_id)
            if result == 'ok':
                self._flight_cache[service_id] = [reserve - 1, volume]  # update cache
        elif service_type == 'hotel':
            result = cancel_hotel_reserve(user_id, service_id)
            if result == 'ok':
                self._flight_cache[service_id] = [reserve - 1, volume]  # update cache
        else:
            return '_no_this_service'
        return result

reserve_service = ReserveService()
